package com.xxx.yuedong.community.websocket;



import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xxx.yuedong.common.R;
import com.xxx.yuedong.community.db.dao.LetterDao;
import com.xxx.yuedong.community.pojo.Letter;
import com.xxx.yuedong.mine.db.dao.UserDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 1、访问登录接口，拿到会话Token：
 *    post http://localhost:9237/user/login
 *    {
 *      "password": "123456",
 *      "username": "jilv"
 *    }
 *
 * 2、找一个WebSocket在线测试页面进行连接，
 * 		例如：
 * 			https://www.bejson.com/httputil/websocket/
 * 		然后连接地址：
 * 			ws://localhost:9237/user/letter?satoken=64b5a372-d81e-437a-8fb6-0248853996f5
 */

/**
 * ws消息处理类
 */
@Component
@Slf4j
public class LetterHandler extends TextWebSocketHandler {

    @Autowired
    private LetterDao letterDao;
    @Autowired
    private UserDao userDao;

    /**
     * 固定前缀
     */
    private static final String USER_ID = "user_id_";

    /**
     * 存放Session集合，方便推送消息
     */

    //                           "user_id_1000", WebSocketSession
    private static ConcurrentHashMap<String, WebSocketSession> webSocketSessionMaps =
            new ConcurrentHashMap<>();


    public String getChatRecords(long userId){
        //查询出所有与该用户有关的聊天信息
        QueryWrapper<Letter> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sender_id", userId).or().eq("receiver_id", userId);
        queryWrapper.orderByAsc("time");//按时间升序
//        queryWrapper.orderByDesc("time");//按时间降序
        List<Letter> letterList = letterDao.selectList(queryWrapper);

        //获取用户列表
        Set<Long> users = new HashSet<>();
        for (Letter letter : letterList){
            long receverId = letter.getReceiverId();
            long senderId = letter.getSenderId();
            users.add(receverId);
            users.add(senderId);
        }
        //不包含用户本身
        users.remove(userId);


        List<Map<String,Object>> letterListVo = new ArrayList<>();
        for (long user : users) {

            Map<String,Object> oneLetter = new HashMap<>();

            HashMap userInfo = userDao.searchUserInfo(user);
            String nickName = (String) userInfo.get("nickName");
            String avatar = (String) userInfo.get("avatar");

            oneLetter.put("userId", user);
            oneLetter.put("nickName", nickName);
            oneLetter.put("avatar", avatar);


            List<Map<String,Object>> contents = new ArrayList<>();
            for (Letter letter : letterList){
                if (letter.getReceiverId() == user || letter.getSenderId() == user){
                    Map<String,Object> content = new HashMap<>();
                    content.put("id", letter.getId());
                    content.put("type", letter.getSenderId() == userId ? 1 : 0);//1为发送出去的消息 0为收到的消息
                    content.put("content", letter.getContent());
                    System.out.println("letter.getTime() = " + letter.getTime());
                    content.put("time", letter.getTime());
                    contents.add(content);
                }
            }
            oneLetter.put("contents", contents);

            letterListVo.add(oneLetter);

        }
        R r = new R();
        r.put("letterList", letterListVo);
        return JSON.toJSONString(r);
    }

    // 监听：连接开启
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // put到集合，方便后续操作
        long userId = (long)session.getAttributes().get("userId");

        webSocketSessionMaps.put(USER_ID + userId, session);
        // 给个提示
        log.debug("Web-Socket 连接成功，sid=" + session.getId() + "，userId=" + userId);

        String chatRecords = getChatRecords(userId);
        sendMessage(session, chatRecords);
    }
    // 收到消息
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        long userId = (long)session.getAttributes().get("userId");
        log.debug("sid为：" + session.getId() + "，发来：" + message);
        String msgJson = message.getPayload();
        try {
            // 解析JSON字符串
            JSONObject jsonObject = JSON.parseObject(msgJson);

            // 获取字段值
            Long receiverId = jsonObject.getLong("receiverId");
            String content = jsonObject.getString("content");
            if (receiverId == null || content == null) {
                throw new JSONException("receiverId字段 或 content字段获取失败");
            }
            // 打印解析结果
            log.debug("receiverId: " + receiverId);
            log.debug("content: " + content);

            Letter letter = new Letter();

            letter.setRead(false);
            letter.setContent(content);
            letter.setSenderId(userId);
            letter.setReceiverId(receiverId);
            letter.setTime(LocalDateTime.now());

            int rows = letterDao.insert(letter);
            if (rows <= 0 ){
                throw new Exception("插入数据库失败");
            }

            String recvContent = getChatRecords(receiverId);
            String sendContent = getChatRecords(userId);

            sendMessage(session,sendContent);
            sendMessage(receiverId,recvContent);

        } catch (JSONException e) {
            String errorStr = "JSON 解析异常 : " + e.getMessage();
            log.debug(errorStr);
            sendMessage(session, JSON.toJSONString(R.error(errorStr)));
        } catch (Exception e){
            sendMessage(session, JSON.toJSONString(R.error(e.getMessage())));
        }


    }

    // 监听：连接关闭
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        // 从集合移除
        String userId = session.getAttributes().get("userId").toString();
        webSocketSessionMaps.remove(USER_ID + userId);

        // 给个提示
        log.debug("Web-Socket 连接关闭，sid=" + session.getId() + "，userId=" + userId);
    }



    // -----------

    // 向指定客户端推送消息
    public static void sendMessage(WebSocketSession session, String message) {
        try {
            log.debug("向sid为：" + session.getId() + "，发送：" + message);
            session.sendMessage(new TextMessage(message));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    // 向指定用户推送消息
    public static void sendMessage(long userId, String message) {
        WebSocketSession session = webSocketSessionMaps.get(USER_ID + userId);
        if(session != null) {
            sendMessage(session, message);
        }
    }
}




